package com.jiangyg.mall.ware.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jiangyg.mall.core.support.restful.Pagination;
import com.jiangyg.mall.core.utils.bean.BeanUtils;
import com.jiangyg.mall.db.mybatis.BaseServiceImpl;
import com.jiangyg.mall.db.mybatis.metadata.Pager;
import com.jiangyg.mall.ware.constant.ColumnConstant;
import com.jiangyg.mall.ware.dao.PurchaseDao;
import com.jiangyg.mall.ware.dao.PurchaseDetailDao;
import com.jiangyg.mall.ware.dao.WareInfoDao;
import com.jiangyg.mall.ware.dto.PurchaseDTO;
import com.jiangyg.mall.ware.entity.Purchase;
import com.jiangyg.mall.ware.entity.PurchaseDetail;
import com.jiangyg.mall.ware.entity.WareInfo;
import com.jiangyg.mall.ware.enums.PurchaseStatus;
import com.jiangyg.mall.ware.vo.PurchaseVO;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PurchaseServiceImpl extends BaseServiceImpl<PurchaseDao, Purchase> implements PurchaseService {

    private final WareInfoDao wareInfoDao;

    private final PurchaseDetailDao purchaseDetailDao;

    @Autowired
    public PurchaseServiceImpl(PurchaseDao purchaseDao,
                               WareInfoDao wareInfoDao,
                               PurchaseDetailDao purchaseDetailDao) {
        super(purchaseDao);
        this.wareInfoDao = wareInfoDao;
        this.purchaseDetailDao = purchaseDetailDao;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public Pagination<PurchaseVO> selectPagination(Pagination<PurchaseVO> pagination) throws Exception {
        Pager<Purchase> pager = new Pager<>();
        pager.setSize(pagination.getSize());
        pager.setCurrent(pagination.getCurrent());
        {
            // 高级查询条件组装
            final QueryWrapper<Purchase> wrapper = this.buildQueryWrapper(pagination, Purchase.class);
            // 普通条件拼接
            final String condition = MapUtils.getString(pagination.toSearchMap(), "condition");
            if (StringUtils.isNotBlank(condition)) {
                wrapper.eq(ColumnConstant.ASSIGNEE_ID, condition).or().eq(ColumnConstant.ASSIGNEE_NAME, condition);
            }
            // 执行查询
            pager = baseMapper.selectPage(pager, wrapper);
        }
        pagination.setRecords(BeanUtils.transformList(pager.getRecords(), PurchaseVO.class));
        pagination.setTotal(pager.getTotal());
        {
            // 如果没查询到数据则直接返回
            if (pager.getTotal() == 0) {
                return pagination;
            }
            // 仓库名称反写
            final List<Long> wareIdList = pager.getRecords().stream()
                    .map(Purchase::getWareId).distinct().collect(Collectors.toList());
            final QueryWrapper<WareInfo> wrapper = new QueryWrapper<>();
            wrapper.in(ColumnConstant.ID, wareIdList);
            final List<WareInfo> wareInfoList = this.wareInfoDao.selectList(wrapper);
            final Map<String, String> wareMap = wareInfoList.stream()
                    .collect(Collectors.toMap(k -> k.getId().toString(), WareInfo::getName));
            pagination.getRecords().forEach(data -> data.setWareName(MapUtils.getString(wareMap, data.getWareId())));
        }
        return pagination;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(PurchaseDTO dto) throws Exception {
        if (dto.getId() == null) {
            dto.setCreateTime(new Date());
        } else {
            dto.setUpdateTime(new Date());
        }
        return this.executeSaveOrUpdate(dto) > 0;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public PurchaseVO selectById(Long purchaseId) throws Exception {
        return this.executeSelectById(purchaseId, PurchaseVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Long> purchaseIds) {
        return this.baseMapper.deleteBatchIds(purchaseIds) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignee(PurchaseDTO dto) {
        // 采购单分配处理
        final int count;
        {
            final Purchase purchase = new Purchase();
            purchase.setAssigneeId(dto.getAssigneeId());
            purchase.setAssigneeName(dto.getAssigneeName());
            purchase.setStatus(PurchaseStatus.ASSIGNED.code);
            final UpdateWrapper<Purchase> wrapper = new UpdateWrapper<>();
            wrapper.eq(ColumnConstant.ID, dto.getId());
            count = this.baseMapper.update(purchase, wrapper);
        }
        // 采购需求分配处理
        final UpdateWrapper<PurchaseDetail> wrapper = new UpdateWrapper<>();
        wrapper.eq(ColumnConstant.PURCHASE_ID, dto.getId());
        final PurchaseDetail purchaseDetail = new PurchaseDetail();
        purchaseDetail.setStatus(PurchaseStatus.ASSIGNED.code);
        this.purchaseDetailDao.update(purchaseDetail, wrapper);
        return count > 0;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<PurchaseVO> unassignedList(Long wareId) throws Exception {
        // 只查询采购单为新建状态的数据
        final QueryWrapper<Purchase> wrapper = new QueryWrapper<>();
        wrapper.eq(ColumnConstant.STATUS, PurchaseStatus.NEW.code);
        wrapper.eq(ColumnConstant.WARE_ID, wareId);
        final List<Purchase> purchaseList = this.baseMapper.selectList(wrapper);
        return BeanUtils.transformList(purchaseList, PurchaseVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean received(List<Long> purchaseIds) {
        // TODO 此处应该有采购人校验以及状态校验：只能领取已分配任务
        // 采购单需求更新
        final int count;
        {
            final UpdateWrapper<Purchase> wrapper = new UpdateWrapper<>();
            wrapper.in(ColumnConstant.ID, purchaseIds);
            final Purchase purchase = new Purchase();
            purchase.setStatus(PurchaseStatus.RECEIVED.code);
            count = this.baseMapper.update(purchase, wrapper);
        }
        // 采购需求状态更新
        final UpdateWrapper<PurchaseDetail> wrapper = new UpdateWrapper<>();
        wrapper.in(ColumnConstant.PURCHASE_ID, purchaseIds);
        final PurchaseDetail detail = new PurchaseDetail();
        detail.setStatus(PurchaseStatus.RECEIVED.code);
        this.purchaseDetailDao.update(detail, wrapper);
        return count > 0;
    }

    @Override
    public boolean finished(List<Long> purchaseIds) {
        // TODO 此处应该有采购人校验以及状态校验，后期可以按采购需求追加应采购、已采购、未采购、未采购原因等细节
        // 采购单需求更新
        final int count;
        {
            final UpdateWrapper<Purchase> wrapper = new UpdateWrapper<>();
            wrapper.in(ColumnConstant.ID, purchaseIds);
            final Purchase purchase = new Purchase();
            purchase.setStatus(PurchaseStatus.FINISHED.code);
            count = this.baseMapper.update(purchase, wrapper);
        }
        // 采购需求状态更新
        final UpdateWrapper<PurchaseDetail> wrapper = new UpdateWrapper<>();
        wrapper.in(ColumnConstant.PURCHASE_ID, purchaseIds);
        final PurchaseDetail detail = new PurchaseDetail();
        detail.setStatus(PurchaseStatus.FINISHED.code);
        this.purchaseDetailDao.update(detail, wrapper);
        return count > 0;
    }

}
